package com.ccteam.fluidmusic.ui.setting

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentEditPasswordBinding
import com.ccteam.fluidmusic.ui.auth.RegisterFragment
import com.ccteam.fluidmusic.utils.EventObserver
import com.ccteam.fluidmusic.utils.VerifyCodeCountDownTimer
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.widget.SNACKBAR_BOTTOM
import com.ccteam.fluidmusic.widget.snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

/**
 * @author Xiaoc
 * @since 2021/4/12
 */
@AndroidEntryPoint
class EditPasswordFragment: Fragment() {

    private var _binding: FragmentEditPasswordBinding? = null
    private val binding get() = _binding!!

    private val editPasswordViewModel by viewModels<EditPasswordViewModel>()

    private val verifyCodeTimer = VerifyCodeCountDownTimer()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentEditPasswordBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        /**
         * 监听倒计时器的状态，根据不同状态更新UI
         */
        viewLifecycleOwner.lifecycleScope.launch {
            verifyCodeTimer.countDown.collectLatest {
                if(it is VerifyCodeCountDownTimer.Status.Timing){
                    updateTiming(it.currentCountDownNum)
                } else {
                    updateNotTiming()
                }
            }
        }

        editPasswordViewModel.enableCountDown.observe(viewLifecycleOwner, EventObserver{
            if(it){
                verifyCodeTimer.start()
            }
        })

        editPasswordViewModel.enableEditPassword.observe(viewLifecycleOwner, {
            binding.btnEditPassword.isEnabled = it
        })

        editPasswordViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.containerEditPassword.isVisible = it is LoadMessage.NotLoading
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
            binding.statusView.changeToErrorStatus(it)
        })

        editPasswordViewModel.editLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnEditPassword.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Success){
                Toast.makeText(requireContext().applicationContext,
                    getString(R.string.description_success_edit_logout),Toast.LENGTH_SHORT).show()
                requireActivity().finish()
            } else if(it is LoadMessage.Error){
                view.snackbar(it.errorMessage.description.toString(), SNACKBAR_BOTTOM).show()
            }
        })

        binding.btnVerify.setProgressButtonOnClickListener{
            editPasswordViewModel.getVerifyCode()
        }

        binding.editPassword.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                if(checkPasswordRegex(text.toString())
                    && text.toString().length in 8..16){
                    editPasswordViewModel.setPasswordSuccess(true)
                    inputLayout.error = null
                } else {
                    editPasswordViewModel.setPasswordSuccess(false)
                    inputLayout.error = getString(R.string.description_error_name_password)
                }
            }
        }

        binding.editPasswordConfirm.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                if(text.toString() != binding.editPassword.editText?.text.toString()){
                    editPasswordViewModel.setPasswordConfirmSuccess(false)
                    inputLayout.error = getString(R.string.description_error_name_password_confirm)
                } else {
                    editPasswordViewModel.setPasswordConfirmSuccess(true)
                    inputLayout.error = null
                }
            }
        }

        binding.editVerifyCode.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                editPasswordViewModel.setVerifySuccess(text.toString().isNotEmpty())
            }
        }

        binding.btnEditPassword.setProgressButtonOnClickListener{
            editPasswordViewModel.editPassword(
                binding.editPasswordConfirm.editText?.text.toString(),
                binding.editVerifyCode.editText?.text.toString()
            )
        }
    }

    /**
     * 判断密码是否符合条件
     * 必须满足 数字，字母，特殊字符两种类型及以上才满足
     * @return true 通过条件 false 不通过
     */
    private fun checkPasswordRegex(password: String): Boolean{
        var i = 0
        if(password.matches(RegisterFragment.REG_NUMBER)){
            i++
        }
        if(password.matches(RegisterFragment.REG_UPPERCASE)){
            i++
        }
        if(password.matches(RegisterFragment.REG_UPPERCASE) || password.matches(RegisterFragment.REG_LOWERCASE)){
            i++
        }
        if(password.matches(RegisterFragment.REG_SYMBOL)){
            i++
        }
        return i >= 2
    }

    /**
     * 更新倒计时数值
     */
    private fun updateTiming(countDownNum: Int){
        binding.btnVerify.isEnabled = false
        binding.btnVerify.text = countDownNum.toString()
    }

    /**
     * 更新停止倒计时的UI
     */
    private fun updateNotTiming(){
        binding.btnVerify.isEnabled = true
        binding.btnVerify.text = getString(R.string.description_get_verification)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        verifyCodeTimer.cancel()

        _binding = null
    }

}